home *** CD-ROM | disk | FTP | other *** search
- #include "emu.h"
- #include "rmov.h"
- #include "const.h"
- #include "compare.h"
-
- void f2xm1()
- {
- if (empty())
- return;
- reg xloga, val, rv, bottom, tmp;
- long i;
-
- r_mul(CONST_LN2, st(), xloga);
- r_mov(xloga, val);
- r_mov(xloga, rv);
-
- for (i=2; i<16; i++)
- {
- r_mov(&i, bottom);
- r_mul(val, xloga, tmp);
- r_div(tmp, bottom, val);
- r_add(val, rv, tmp);
- r_mov(tmp, rv);
- }
- r_mov(rv, st());
- }
-
- // logb(x) = loga(x) / loga(b)
- // log2(x) = loge(x) / loge(2)
-
- void fyl2x()
- {
- if (empty())
- return;
- reg frac2, sum, div, term, pow, temp;
- r_sub(st(), CONST_1, frac2);
- r_add(st(), CONST_1, div);
- r_div(frac2, div, sum);
- r_mul(sum, sum, frac2);
- r_mul(sum, st(1), pow);
- for (long i=3; i<15; i+=2)
- {
- r_mul(pow, frac2, temp);
- r_mov(temp, pow);
- r_mov(&i, div);
- r_div(temp, div, term);
- r_add(term, sum, temp);
- r_mov(temp, sum);
- }
- r_div(sum, CONST_LN2, temp);
- temp.exp++;
- r_mov(temp, st(1));
- st().tag = TW_E;
- top++;
- }
-
- void fptan()
- {
- extern void fsincos();
- fsincos();
- if (empty(1))
- return;
- reg tmp;
- r_div(st(1), st(), tmp);
- r_mov(tmp, st(1));
- r_mov(CONST_1, st());
- }
-
- void fpatan()
- {
- if (empty(1))
- return;
- if (mag_same(st(), CONST_Z))
- {
- r_mov(CONST_PI2, st(1));
- st().tag = TW_E;
- top++;
- return;
- }
- if (mag_same(st(1), CONST_Z))
- {
- r_mov(CONST_Z, st(1));
- st().tag = TW_E;
- top++;
- return;
- }
- reg x2, sum, term, pow, temp;
- int quadrant = 0;
- if (st(1).sign == SIGN_NEG)
- quadrant |= 1;
- if (st(0).sign == SIGN_NEG)
- quadrant |= 2;
- st(1).sign = st().sign = SIGN_POS;
- if (compare(st(1), st()) == COMP_A_GT_B)
- {
- quadrant |= 4;
- r_mov(st(1), temp);
- r_mov(st(), st(1));
- r_mov(temp, st());
- }
-
- r_div(st(1), st(), sum);
- r_mul(sum, sum, x2);
- r_mov(sum, pow);
-
- x2.sign ^= SIGN_POS^SIGN_NEG;
-
- for (long i=3; i<25; i+=2)
- {
- r_mul(pow, x2, temp);
- r_mov(temp, pow);
- r_mov(&i, temp);
- r_div(pow, temp, term);
- r_add(sum, term, temp);
- r_mov(temp, sum);
- }
-
- if (quadrant & 4)
- {
- r_sub(CONST_PI2, sum, temp);
- r_mov(temp, sum);
- }
- if (quadrant & 2)
- {
- r_sub(CONST_PI, sum, temp);
- r_mov(temp, sum);
- }
- if (quadrant & 1)
- sum.sign ^= SIGN_POS^SIGN_NEG;
-
- r_mov(sum, st(1));
- st().tag = TW_E;
- top++;
- }
-
- void fxtract()
- {
- if (empty())
- return;
- if (full())
- return;
- top--;
- r_mov(st(1), st());
- st().exp = EXP_BIAS;
- long e = st(1).exp - EXP_BIAS;
- r_mov(&e, st(1));
- }
-
- extern int fprem_do(reg&,reg&,int);
-
- void fprem1()
- {
- if (empty(1))
- return;
- int q = fprem_do(st(), st(1), RC_RND);
- if (q == -1)
- setcc(SW_C2);
- else
- {
- int c = 0;
- if (q&4) c |= SW_C3;
- if (q&2) c |= SW_C1;
- if (q&1) c |= SW_C0;
- setcc(c);
- }
- }
-
- void fdecstp()
- {
- top--;
- }
-
- void fincstp()
- {
- top++;
- }
-
- FUNC emu_16_table[] = {
- f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp
- };
-
- void emu_16()
- {
- if (modrm > 0277)
- {
- (emu_16_table[modrm&7])();
- }
- else
- {
- emu_bad();
- }
- }
-
-